package com.example.shop_front_api.controller;

import com.example.shop_front_api.entity.Goods;
import com.example.shop_front_api.entity.News;
import com.example.shop_front_api.utils.JsonResult;
import com.example.shop_front_api.utils.Tool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.HighlightQuery;
import org.springframework.data.elasticsearch.core.query.highlight.Highlight;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightField;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightParameters;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("api/search")
public class SearchController {

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    @GetMapping("createIndex")
    public JsonResult createIndex(@RequestParam String type) {
        if ("news".equals(type)) {
            IndexOperations indexOperations = elasticsearchOperations.indexOps(News.class);
            if (!indexOperations.exists()) {
                indexOperations.create();
            }
            return JsonResult.success("资讯索引创建成功", null);
        } else if ("goods".equals(type)) {
            IndexOperations indexOperations = elasticsearchOperations.indexOps(Goods.class);
            if (!indexOperations.exists()) {
                indexOperations.create();
            }
            return JsonResult.success("商品索引创建成功", null);
        }
        return JsonResult.failed("类型错误，支持: news, goods");
    }

    // 添加文档
    @PostMapping("addToES")
    public JsonResult addToES(@RequestBody Object entity, @RequestParam String type) {
        if ("news".equals(type) && entity instanceof News) {
            News news = (News) entity;
            news.setCreateTime(Tool.getCurrentTime());
            News result = elasticsearchOperations.save(news);
            return JsonResult.success("资讯添加成功", result);
        } else if ("goods".equals(type) && entity instanceof Goods) {
            Goods goods = (Goods) entity;
            Goods result = elasticsearchOperations.save(goods);
            return JsonResult.success("商品添加成功", result);
        }
        return JsonResult.failed("添加失败，类型不匹配");
    }

    // 删除文档
    @GetMapping("deleteFromES")
    public JsonResult deleteFromES(@RequestParam Long id, @RequestParam String type) {
        if (id == null) {
            return JsonResult.failed("id不能为空");
        }
        if ("news".equals(type)) {
            String result = elasticsearchOperations.delete(id.toString(), News.class);
            return JsonResult.success("资讯删除成功", null);
        } else if ("goods".equals(type)) {
            String result = elasticsearchOperations.delete(id.toString(), Goods.class);
            return JsonResult.success("商品删除成功", null);
        }
        return JsonResult.failed("类型错误，支持: news, goods");
    }

    // 搜索资讯
    @GetMapping("searchNews")
    public JsonResult searchNews(@RequestParam(value = "wd", required = false) String wd) {
        if (wd == null || wd.isEmpty()) {
            SearchHits<News> hits = elasticsearchOperations.search(
                    NativeQuery.builder().build(), News.class
            );
            List<News> newsList = hits.stream()
                    .map(SearchHit::getContent)
                    .collect(Collectors.toList());
            return JsonResult.success("查询成功", newsList);
        }

        Criteria criteria = new Criteria("title").contains(wd);
        CriteriaQuery query = new CriteriaQuery(criteria);
        SearchHits<News> hits = elasticsearchOperations.search(query, News.class);
        List<News> newsList = hits.stream()
                .map(SearchHit::getContent)
                .toList();
        return JsonResult.success("搜索成功", newsList);
    }

    // 搜索商品
    @GetMapping("searchGoods")
    public JsonResult searchGoods(@RequestParam(value = "wd", required = false) String wd) {
        if (wd == null || wd.isEmpty()) {
            SearchHits<Goods> hits = elasticsearchOperations.search(
                    NativeQuery.builder().build(), Goods.class
            );
            List<Goods> goodsList = hits.stream()
                    .map(SearchHit::getContent)
                    .collect(Collectors.toList());
            return JsonResult.success("查询成功", goodsList);
        }

        Criteria criteria = new Criteria("goodsName").contains(wd);
        CriteriaQuery query = new CriteriaQuery(criteria);
        SearchHits<Goods> hits = elasticsearchOperations.search(query, Goods.class);
        List<Goods> goodsList = hits.stream()
                .map(SearchHit::getContent)
                .toList();
        return JsonResult.success("搜索成功", goodsList);
    }

    // 高亮搜索
    @GetMapping("highlightSearch")
    public JsonResult highlightSearch(@RequestParam String wd, @RequestParam String type) {
        NativeQueryBuilder queryBuilder = NativeQuery.builder();

        HighlightField highlightField;
        if ("news".equals(type)) {
            highlightField = new HighlightField("title");
            queryBuilder.withQuery(q -> q.match(m -> m.field("title").query(wd)));
        } else if ("goods".equals(type)) {
            highlightField = new HighlightField("goodsName");
            queryBuilder.withQuery(q -> q.match(m -> m.field("goodsName").query(wd)));
        } else {
            return JsonResult.failed("类型错误，支持: news, goods");
        }

        HighlightParameters parameters = HighlightParameters.builder()
                .withPreTags("<span style='color: red'>")
                .withPostTags("</span>")
                .withFragmentSize(Integer.MAX_VALUE)
                .withNumberOfFragments(1)
                .build();
        Highlight highlight = new Highlight(parameters, List.of(highlightField));
        HighlightQuery highlightQuery = new HighlightQuery(highlight,
                "news".equals(type) ? News.class : Goods.class);

        queryBuilder.withHighlightQuery(highlightQuery)
                .withPageable(PageRequest.of(0, 50));

        if ("news".equals(type)) {
            SearchHits<News> searchHits = elasticsearchOperations.search(queryBuilder.build(), News.class);
            HashMap<String, Object> resultData = new HashMap<>();
            resultData.put("hits", searchHits.getSearchHits());
            resultData.put("totalHits", searchHits.getTotalHits());
            return JsonResult.success("资讯高亮搜索成功", resultData);
        } else {
            SearchHits<Goods> searchHits = elasticsearchOperations.search(queryBuilder.build(), Goods.class);
            HashMap<String, Object> resultData = new HashMap<>();
            resultData.put("hits", searchHits.getSearchHits());
            resultData.put("totalHits", searchHits.getTotalHits());
            return JsonResult.success("商品高亮搜索成功", resultData);
        }
    }

    // 根据ID查询
    @GetMapping("getFromES")
    public JsonResult getFromES(@RequestParam Long id, @RequestParam String type) {
        if (id == null) {
            return JsonResult.failed("id不能为空");
        }
        if ("news".equals(type)) {
            News news = elasticsearchOperations.get(id.toString(), News.class);
            if (news == null) {
                return JsonResult.failed("资讯不存在");
            }
            return JsonResult.success("查询成功", news);
        } else if ("goods".equals(type)) {
            Goods goods = elasticsearchOperations.get(id.toString(), Goods.class);
            if (goods == null) {
                return JsonResult.failed("商品不存在");
            }
            return JsonResult.success("查询成功", goods);
        }
        return JsonResult.failed("类型错误，支持: news, goods");
    }

    // 检查文档是否存在
    @GetMapping("existsInES")
    public JsonResult existsInES(@RequestParam Long id, @RequestParam String type) {
        if (id == null) {
            return JsonResult.failed("id不能为空");
        }
        boolean exists;
        if ("news".equals(type)) {
            exists = elasticsearchOperations.exists(id.toString(), News.class);
        } else if ("goods".equals(type)) {
            exists = elasticsearchOperations.exists(id.toString(), Goods.class);
        } else {
            return JsonResult.failed("类型错误，支持: news, goods");
        }
        return JsonResult.success(exists ? "文档存在" : "文档不存在", exists);
    }
}